#include <2025Linux.h>
int modeToStr(mode_t mode, char *str){
    // 40666 --> "drw-rw-rw-"
    // stat的帮助手册里面有示例
    switch (mode & S_IFMT) {
    case S_IFBLK:  str[0] = 'b';break;
    case S_IFCHR:  str[0] = 'c';break;
    case S_IFDIR:  str[0] = 'd';break;
    case S_IFIFO:  str[0] = 'p';break;
    case S_IFLNK:  str[0] = 'l';break;
    case S_IFREG:  str[0] = '-';break;
    case S_IFSOCK: str[0] = 's';break;
    default:       str[0] = '?';break;
    }
    int i = 1<<8; // 100 000 000  
    if(mode & i){
        str[1] = 'r';
    }
    else{
        str[1] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[2] = 'w';
    }
    else{
        str[2] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[3] = 'x';
    }
    else{
        str[3] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[4] = 'r';
    }
    else{
        str[4] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[5] = 'w';
    }
    else{
        str[5] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[6] = 'x';
    }
    else{
        str[6] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[7] = 'r';
    }
    else{
        str[7] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[8] = 'w';
    }
    else{
        str[8] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[9] = 'x';
    }
    else{
        str[9] = '-';
    }
    str[10] = '\0';
    return 0;
}
int timeToStr(time_t mtime, char *str){
    // time_t ---> Dec 14 11:45 月 日 时:分
    struct tm* tmVal = localtime(&mtime);
    char monStr[][5] = {"Jan","Feb","Mar","Apr","May","Jun",
                       "Jul","Aug","Sep","Oct","Nov","Dec"};
    int mon = tmVal->tm_mon;
    int mday = tmVal->tm_mday;
    int hour = tmVal->tm_hour;
    int min = tmVal->tm_min;
    
    sprintf(str,"%s %02d %02d:%02d",monStr[mon],mday,hour,min);
    return 0;
}
int main(int argc, char *argv[])
{
    // ./01_ls_al dir1
    ARGS_CHECK(argc,2);
    DIR * dirp = opendir(argv[1]);
    ERROR_CHECK(dirp,NULL,"opendir");
    struct dirent * direntp;
    chdir(argv[1]);//把当前工作目录切换过去
    while((direntp = readdir(dirp)) != NULL){
        struct stat statbuf;
        int ret = stat(direntp->d_name,&statbuf); //切换目录之后，文件名就是文件路径
        ERROR_CHECK(ret,-1,"stat");
        char modeStr[11] = {0};
        modeToStr(statbuf.st_mode,modeStr);
        char dateStr[128] = {0};
        timeToStr(statbuf.st_mtime,dateStr);
        printf("%s %2ld %s %s %8ld %s %s\n",
               modeStr, // 文件的类型和权限
               statbuf.st_nlink, // 文件的硬链接数
               getpwuid(statbuf.st_uid)->pw_name, //根据uid得到的用户名
               getgrgid(statbuf.st_gid)->gr_name, // 根据gid得到的组名
               statbuf.st_size, //文件的大小
               dateStr, //文件的时间
               direntp->d_name //文件的名字
        );
    }
    closedir(dirp);
    return 0;
}

